package labox.innovation.gameserver.model.actor.stat;

import labox.innovation.config.Config;
import labox.innovation.gameserver.datatables.Experience;
import labox.innovation.gameserver.model.FriendNewsFactory;
import labox.innovation.gameserver.model.FriendsNews;
import labox.innovation.gameserver.model.L2PetDataTable;
import labox.innovation.gameserver.model.actor.instance.FuzePcInstance;
import labox.innovation.gameserver.network.SystemMessageId;
import labox.innovation.gameserver.network.serverpackets.StatusUpdate;
import labox.innovation.gameserver.network.serverpackets.SystemMessage;
import labox.innovation.gameserver.network.serverpackets.UserInfo;
import labox.innovation.gameserver.skills.Stats;

public class PcStat extends PlayableStat {
	//private static Logger _log = Logger.getLogger(PcStat.class.getName());

	// =========================================================
	// Data Field
	private int _oldMaxHp;

	private int _oldMaxMp;

	/**
	 * 是否启用了自动升级
	 */
	private boolean _autoAddLevel;

	// =========================================================
	// Constructor
	public PcStat(FuzePcInstance activeChar) {
		super(activeChar);
		//		initCharStatusUpdateValues();
	}

	/**
	 * 获取杀怪经验率
	 */
	public float getKillMobExpRate() {
		return calcStat(Stats.KILL_MOB_EXP_RATE, getActiveChar().getTemplate().getBaseKillMobExpRate(), null, null);
	}

	/**
	 * 杀怪经验额外值
	 */
	public int getKillMobExp() {
		return (int) calcStat(Stats.KILL_MOB_EXP, getActiveChar().getTemplate().getBaseKillMobExp(), null, null);
	}

	/**
	 * 任务经验系数
	 */
	public float getQuestExp() {
		return calcStat(Stats.QUEST_EXP, getActiveChar().getTemplate().getBaseQuestExpRate(), null, null);
	}

	/**
	 * 商店购买系数
	 */
	public float getShopBuyRate() {
		return calcStat(Stats.SHOP_BUY_RATE, getActiveChar().getTemplate().getBaseShopBuyRate(), null, null);
	}

	/**
	 * 商店出售系数
	 */
	public float getShopSellRate() {
		return calcStat(Stats.SHOP_SELL_RATE, getActiveChar().getTemplate().getBaseShopSellRate(), null, null);
	}

	/**
	 * 商店修理系数
	 */
	public float getShopRepairRate() {
		return calcStat(Stats.SHOP_REPAIR_RATE, getActiveChar().getTemplate().getBaseShopRepairRate(), null, null);
	}

	/**
	 * 商城购买系数
	 */
	public float getMallBuyRate() {
		return calcStat(Stats.MALL_BUY_RATE, getActiveChar().getTemplate().getBaseMallBuyRate(), null, null);
	}

	/**
	 * 装备品质掉落系数
	 */
	public float getItemQualityRate() {
		return calcStat(Stats.ITEM_QUALITY_RATE, getActiveChar().getTemplate().getBaseItemQualityRate(), null, null);
	}

	/**
	 * 装备品质掉落系数
	 */
	public float getItemAmountRate() {
		return calcStat(Stats.ITEM_AMOUNT_RATE, getActiveChar().getTemplate().getBaseItemAmountRate(), null, null);
	}

	/**
	 * 装备品质掉落系数
	 */
	public float getExploitRate() {
		return calcStat(Stats.EXPLOIT_RATE, getActiveChar().getTemplate().getBaseExploitRate(), null, null);
	}

	//经验条长
	protected int _barExpPixels = 240;

	//经验更新间隔
	protected int _expUpdateInterval;

	protected int _expUpdateIncCheck;

	protected int _expUpdateDecCheck;

	public void initCharStatusUpdateValues() {
		_expUpdateInterval = getNextLevelNeedExperience() / _barExpPixels; // MAX_HP div MAX_HP_BAR_PX HP更新间隔
		if (_expUpdateInterval == 0) {
			_expUpdateInterval = 1;
		}

		_expUpdateInterval *= 25;
		_expUpdateIncCheck = getNextLevelNeedExperience();
		_expUpdateDecCheck = getNextLevelNeedExperience() - _expUpdateInterval;

	}

	
	int firstUpdate = 0;
	
	/**
	 * 是否需要更新 经验条
	 * @param barPixels
	 * @return
	 */
	protected boolean needExpUpdate(int barPixels) {

		int currentExp = getExp();

		//如果当前经验 大于最大升级经验 不再更新
		//说明 人物角色还没升级
		if ( currentExp > getNextLevelNeedExperience() ) {
			if( firstUpdate <= 0  ){
				firstUpdate ++;
//				return true;
			}else{
				return false;
			}
		}else{
			firstUpdate = 0;
		}
		
		
		//如果 当前Exp小于1， 或者 当前最大的Exp没有超出 显示的像素。  那么一直更新
		if (currentExp <= 1 || getNextLevelNeedExperience() < barPixels)
			return true;

		//如果当前Exp小于Exp更新的下限 或者 当前Exp大于Exp更新的上限
		//那么需要更新 Exp, 并且重新计算下次Exp更新的上下限
		if (currentExp <= _expUpdateDecCheck || currentExp >= _expUpdateIncCheck) {

			if (currentExp >= getNextLevelNeedExperience()) {
				//如果当前Exp=最大的Exp, 那么下次Exp的更新上限为最大Exp+1; 下限为最大Exp- Exp的更新间隔值
				_expUpdateIncCheck = currentExp + 1;
				_expUpdateDecCheck = currentExp - _expUpdateInterval;
			} else {
				//如果当前Exp不等于最大Exp。  那么计算出当前Exp是 更新间隔值的 倍率
				//下次Exp更新下限为 更新倍率*Exp更新间隔值. Exp更新上限值为下限值+更新间隔值
				int intMulti = currentExp / _expUpdateInterval;

				_expUpdateDecCheck = _expUpdateInterval * intMulti;
				_expUpdateIncCheck = _expUpdateDecCheck + _expUpdateInterval;
			}

			return true;
		}
		

		return false;
	}

	@Override
	public boolean addExp(int value, boolean fullcheckLevelUp) {
		//连接权限是否允许增加经验
		if (!getActiveChar().getAccessLevel().canGainExp())
			return false;

		if (_autoAddLevel) {
			if (!super.addExp(value, fullcheckLevelUp))
				return false;
		} else {
			if (!addBaseExp(value))
				return false;
		}

		//TODO:
		//增加 经验更新通知
		if (needExpUpdate(_barExpPixels)) {
			StatusUpdate su = new StatusUpdate(getActiveChar().getObjectId());
			su.addAttribute(StatusUpdate.EXP, getExpRadio());//TODO 这里应该是比例
			getActiveChar().sendPacket(su);
		}

		return true;
	}

	/**
	 * 玩家等级升级时的处理逻辑
	 */
	@Override
	public final boolean addLevel(int value, boolean sendInfo) {
		int cur_level = getLevel();
		boolean levelIncreased = super.addLevel(value, sendInfo);

		if (levelIncreased) {
			FuzePcInstance player = getActiveChar();

			//每升一级加2点未分配的属性点
			setUnassignedPoint(getUnassignedPoint() + (getLevel() - cur_level) * Config.LEVELUP_UNASSIGNPOINT);

			//player.broadcastPacket(new SocialAction(player.getObjectId(), SocialAction.LEVEL_UP));
			player.sendPacket(new SystemMessage(SystemMessageId.YOU_INCREASED_YOUR_LEVEL));
			//L2ClassMasterInstance.showQuestionMark(player);

			//道具限制检查
			player.checkItemRestriction();
			if (player.getClan() != null) {
				player.getClan().updateClanMember(player);
				//player.getClan().broadcastToOnlineMembers(new PledgeShowMemberListUpdate(player));
			}
			if (player.isInParty())
				player.getParty().recalculatePartyLevel(); // Recalculate the party level

			if (player.isTransformed() || player.isInStance())
				player.getTransformation().onLevelUp();

			StatusUpdate su = new StatusUpdate(player.getObjectId());
			su.addAttribute(StatusUpdate.LEVEL, getLevel());
			su.addAttribute(StatusUpdate.EXP, getExpRadio());
			su.addAttribute(StatusUpdate.HP, getActiveChar().getCurrentHpRadio());//TODO 这里应该是比例
			su.addAttribute(StatusUpdate.MP, getActiveChar().getCurrentMpRadio());
			player.sendPacket(su);

			if (sendInfo) {
				// Send a Server->Client packet UserInfo to the L2PcInstance
				player.sendPacket(new UserInfo(player));
			}
			player.refreshMayQuestList();// 刷新可接任务列表
			
			//给加我为好友的人发送我升级消息
			FriendsNews news=FriendNewsFactory.creatUpLeveMessage(getActiveChar());
			getActiveChar().getFriendInstance().getNewsManager().sendMessage(news,null);
			
		}

		initCharStatusUpdateValues();
		return levelIncreased;
	}

	@Override
	public final int getExpForLevel(int level) {
		return Experience.LEVEL[level];
	}

	// =========================================================
	// Method - Private

	// =========================================================
	// Property - Public
	@Override
	public final FuzePcInstance getActiveChar() {
		return (FuzePcInstance) _activeChar;
	}

	@Override
	public final void setLevel(int value) {
		if (value > Experience.MAX_LEVEL)
			value = Experience.MAX_LEVEL;
		super.setLevel(value);
	}

	@Override
	public final int getMaxHp() {
		// Get the Max HP (base+modifier) of the L2PcInstance
		int val = super.getMaxHp();
		if (val != _oldMaxHp) {
			_oldMaxHp = val;

			// Launch a regen task if the new Max HP is higher than the old one
//			if (getActiveChar().getStatus().getCurrentHp() != val)
//				getActiveChar().getStatus().setCurrentHp(getActiveChar().getStatus().getCurrentHp()); // trigger start of regeneration
		}

		return val;
	}

	@Override
	public final int getMaxMp() {
		// Get the Max MP (base+modifier) of the L2PcInstance
		int val = super.getMaxMp();

		if (val != _oldMaxMp) {
			_oldMaxMp = val;

			// Launch a regen task if the new Max MP is higher than the old one
//			if (getActiveChar().getStatus().getCurrentMp() != val)
//				getActiveChar().getStatus().setCurrentMp(getActiveChar().getStatus().getCurrentMp()); // trigger start of regeneration
		}

		return val;
	}

	@Override
	public int getRunSpeed() {
		if (getActiveChar() == null)
			return 1;
		int val = 0;
		FuzePcInstance player = getActiveChar();
		if (player.isMounted()) {
			int baseRunSpd = L2PetDataTable.getInstance().getPetData(player.getMountNpcId(), player.getMountLevel()).getPetSpeed();
			val = (int) calcStat(Stats.RUN_SPEED, baseRunSpd, null, null);
		} else {
			val = super.getRunSpeed();
		}
		return val;
	}

	public boolean getAutoAddLevel() {
		return _autoAddLevel;
	}

	public void setAutoAddLevel(boolean auto) {
		_autoAddLevel = auto;
		if (auto) {
			checkLevelUp(true, true);
		}
	}

	/**
	 * 获得当前经验 比率  %比
	 * @return
	 */
	public int getExpRadio() {
		//如果已达到最高级  直接返回 100%
		if (getLevel() >= Experience.MAX_LEVEL)
			return 100;

		if (getNextLevelNeedExperience() == 0) {
			return 0;
		}
		int radio = (getExp() * 100) / getNextLevelNeedExperience();

		return radio < 100 ? radio : 100;
	}

	public int getNextLevelNeedExperience() {
		if (getLevel() >= Experience.MAX_LEVEL)
			return 0;
		return Experience.LEVEL[getLevel() + 1];
	}
}
